const path = require('path');
const fs = require("fs").promises;
const ffmpeg = require('fluent-ffmpeg');
/**
 * use全局参数
 * agreement 协议头
 */
/*上传视频*/
const upload_file_video = (req, res) => {
	let obj_file = {
		code: -1,
		path: "",
		type: "",
		msg: "上传失败"
	};
	try {
		res.header("Access-Control-Allow-Origin", "*");
		let file = req.file || 'null';
		let filetype = (req.file && req.file.mimetype) || 'null';
		obj_file.type = filetype

		if (file === 'null') {
			obj_file.msg = "请上传文件";
			res.end(JSON.stringify(obj_file));
			return;
		}
		const {
			originalname,
			filename,
			mimetype,
			size
		} = file;
		let newFilePath, newThumbnailPath, newHlsPath; //视频 封面  m3u8
		let orsrc = `${path.basename(filename, path.extname(filename))}`;
		let newfilename = `vt_${orsrc}.webp`
		if (isProd) {
			newFilePath = `${agreement}://${req.hostname}/videos/${filename}`;
			newThumbnailPath = `${agreement}://${req.hostname}/videos_thumbnail/${newfilename}`;
			newHlsPath = `${agreement}://${req.hostname}/videos_hls/${orsrc}/index.m3u8`;
		} else {
			newFilePath = `${agreement}://${req.hostname}:${port}/videos/${filename}`;
			newThumbnailPath = `${agreement}://${req.hostname}:${port}/videos_thumbnail/${newfilename}`;
			newHlsPath = `${agreement}://${req.hostname}:${port}/videos_hls/${orsrc}/index.m3u8`;
		}
		let dirPath = `/videos/${filename}`;
		// 如果是视频文件，则处理封面
		let thumbnail = null;
		//保存在文件夹中的位置
		const thumbnailPath = path.join(rootDirname, 'public/videos_thumbnail', newfilename);
		let p1 = new Promise((resolve, reject) => {
			ffmpeg(file.path)
				.format('webp') // 指定输入格式 
				.on('error', (err) => {
					reject(err)
				})
				.on('end', () => {
					resolve()
				})
				.screenshot({
					timemarks: ["00:00:01"], // 指定截取的时间点，单位为秒, 设置为1秒，因为精确到0秒可能会因为编解码延迟而错过第一帧
					filename: path.basename(thumbnailPath), // 输出文件名
					folder: path.dirname(thumbnailPath), // 输出文件夹
					size: '540x960' // 输出图片尺寸 1080x1920
				})
		})
		Promise.all([p1]).then(() => {
			obj_file = {
				...obj_file,
				code: 200,
				msg: "上传成功",
				originalname,
				filename,
				path: newFilePath,
				dirPath,
				mimetype,
				size,
				thumbnail: newThumbnailPath,
				m3u8path: newHlsPath
			}
			handledCompress(filename, orsrc);
			res.end(JSON.stringify(obj_file));
		}).catch(err => {
			obj_file.msg = err.message
			res.end(JSON.stringify(obj_file));
		})

	} catch (e) {
		obj_file.msg = e.message
		res.end(JSON.stringify(obj_file));
	}
}
/**处理单个视频文件的压缩和切片
 *@param {*} filename 文件名称及后缀
 *@param {*} orsrc 文件名称
 */
async function handledCompress(filename, orsrc) {
	let videoInputStream, videoOutputFile, inputStream, outputFile;
	try {
		videoInputStream = "public/videos/" + filename;
		videoOutputFile = "public/video_compress/" + filename;
		inputStream = videoInputStream;
		outputFile = `public/videos_hls/${orsrc}/index.m3u8`;

		await fs.access(videoInputStream, fs.constants.F_OK);
		// 检查并创建输出文件夹
		await fs.mkdir(path.dirname(videoOutputFile), {
			recursive: true
		});
		await fs.mkdir(`public/videos_hls/${orsrc}`, {
			recursive: true
		});

		// 压缩视频
		await new Promise((resolve, reject) => {
			ffmpeg()
				.input(videoInputStream)
				.videoCodec('libx264')
				.outputOptions('-b:v 600k')
				.outputOptions('-s 720x1280')
				.output(videoOutputFile)
				.on('error', reject)
				.on('end', async () => {
					//移动位置 替换
					await fs.rename(videoOutputFile, videoInputStream, (err) => {
						if (err) {
							inputStream = videoOutputFile;
						}
					});
					resolve();
				})
				.run();
		});

		// 切片视频为 HLS
		await new Promise((resolve, reject) => {
			ffmpeg()
				.input(inputStream)
				.videoCodec('libx264')
				.outputOptions([
					'-hls_time 5',
					'-hls_list_size 0',
					'-f hls'
				])
				.output(outputFile)
				.on('error', reject)
				.on('end', () => {
					console.log("切片处理完毕", outputFile);
					resolve();
				})
				.run();
		});

	} catch (err) {
		if (err.code === 'ENOENT') {
			console.error(`文件 ${videoInputStream} 不存在，跳过压缩和切片。`);
		} else {
			console.error('Error during compression, slicing, or file access:', err);
		}
	}
}
module.exports = upload_file_video;